<?php
/**
 * Created by PhpStorm.
 * User: xuezhileikaku
 * Email:chengyingbo88@163.com
 * Date: 2024/8/23
 * Time: 下午6:16
 */

namespace App;


namespace App;

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
use Psr\EventDispatcher\EventDispatcherInterface;
use App\Routing\Router;
use App\Config\Config;
use App\Service\ServiceRegistry;
use App\Event\ListenerProvider;
use App\Event\RequestReceivedEvent;
use App\Event\ResponseSentEvent;
use GuzzleHttp\Psr7\ServerRequest;
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;

class App implements RequestHandlerInterface
{
    private $container;
    private $logger;
    private $dispatcher;
    private $router;
    private $middlewares = [];

    public function __construct(ContainerInterface $container, LoggerInterface $logger, EventDispatcherInterface $dispatcher, Router $router)
    {
        $this->container = $container;
        $this->logger = $logger;
        $this->dispatcher = $dispatcher;
        $this->router = $router;
    }

    public function addMiddleware(MiddlewareInterface $middleware): void
    {
        $this->middlewares[] = $middleware;
    }

    public function handle(RequestInterface $request): ResponseInterface
    {
        $this->logger->info('Handling request...', ['uri' => $request->getUri()]);
        $this->dispatcher->dispatch(new RequestReceivedEvent($request));

        $response = $this->process($request);

        $this->dispatcher->dispatch(new ResponseSentEvent($response));
        $this->logger->info('Response sent', ['status' => $response->getStatusCode()]);

        return $response;
    }

    private function process(RequestInterface $request): ResponseInterface
    {
        $handler = array_reduce(
            array_reverse($this->middlewares),
            function ($nextHandler, MiddlewareInterface $middleware) {
                return new class($middleware, $nextHandler) implements RequestHandlerInterface {
                    private $middleware;
                    private $nextHandler;

                    public function __construct(MiddlewareInterface $middleware, RequestHandlerInterface $nextHandler)
                    {
                        $this->middleware = $middleware;
                        $this->nextHandler = $nextHandler;
                    }

                    public function handle(RequestInterface $request): ResponseInterface
                    {
                        return $this->middleware->process($request, $this->nextHandler);
                    }
                };
            },
            $this->router
        );

        return $handler->handle($request);
    }

    public function run(): void
    {
        // 加载配置
        $config = $this->container->get(Config::class);

        // 设置服务注册表
        $serviceRegistry = $this->container->get(ServiceRegistry::class);
        foreach ($config->get('services') as $name => $address) {
            $serviceRegistry->register($name, $address);
        }

        // 注册事件监听器
        $listenerProvider = $this->container->get(ListenerProvider::class);
        $listenerProvider->addListener(RequestReceivedEvent::class, function (RequestReceivedEvent $event) {
            $this->logger->info('Request received: ' . $event->getRequest()->getUri());
        });
        $listenerProvider->addListener(ResponseSentEvent::class, function (ResponseSentEvent $event) {
            $this->logger->info('Response sent with status: ' . $event->getResponse()->getStatusCode());
        });

        // 处理 HTTP 请求
        $request = ServerRequest::fromGlobals();
        $response = $this->handle($request);

        // 发送 HTTP 响应
        $emitter = new SapiEmitter();
        $emitter->emit($response);
    }
}
